package com.climber.android.commonres.ui

import android.app.Activity
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.res.TypedArray
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.view.KeyEvent
import android.view.View
import androidx.appcompat.app.AlertDialog
import com.alibaba.android.arouter.launcher.ARouter
import com.climber.android.commonres.R
import com.climber.android.commonres.aidl.AuthServiceAIDL
import com.climber.android.commonres.app.AppAccount
import com.climber.android.commonsdk.app.AppConstants
import com.climber.android.commonres.helper.PermissionReallyDeclinedImpl
import com.climber.android.commonres.ui.dialog.CommonHorizontalActionsDialog
import com.climber.android.commonres.ui.dialog.CommonVerticalActionsDialog
import com.climber.android.commonres.util.UIHelper
import com.climber.android.commonsdk.api.APIErrorToast
import com.climber.android.commonsdk.arouter.ARouterPathConstants
import com.climber.android.commonsdk.event.BusProvider
import com.climber.android.commonsdk.event.CommonBusEvent
import io.android.library.titlebar.SmartTitleBar
import io.ganguo.library.klog.KLog
import io.ganguo.library.mvp.AppManager
import io.ganguo.library.mvp.arouter.BundleHelper
import io.ganguo.library.mvp.fragment_handle.FragmentHandleBackUtil
import io.ganguo.library.mvp.ui.mvp.IPresenter
import io.ganguo.library.mvp.ui.mvp.base.IBaseActivity
import io.ganguo.library.mvp.util.*
import io.ganguo.library.rxpermissions.RuntimePermissionUtil
import io.library.android.net.NetworkManager
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

/**
 * Created by Mikes at 2019/6/3 11:47 AM
 */
abstract class BaseMVPActivity<P : IPresenter> : IBaseActivity<P>() {
    private var smartTitleBar: SmartTitleBar?=null
    protected fun getSmartToolBar() : SmartTitleBar? = smartTitleBar

    override fun ignoreSystemFontScale(): Boolean = true

    open fun changeStatusColor() : Boolean = true

    override fun onCreate(savedInstanceState: Bundle?) {
        if(!BusProvider.getInstance().isRegistered(this)){
            BusProvider.getInstance().register(this)
        }
        AppManager.getInstance().addActivity(this)
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            val result = fixOrientation()
            KLog.i(AppConstants.LOG_TAG, "onCreate fixOrientation when Oreo, result = $result")
        }
        if(changeStatusColor()){
            StatusBarUtils.changeStatusBarColor(this, UIUtils.getColor(R.color.status_bar_color))
        }

        ARouter.getInstance().inject(this)

        super.onCreate(savedInstanceState)
    }

    override fun setContentView(layoutResID: Int) {
        super.setContentView(layoutResID)

        findAndInitToolBar()
    }

    private fun findAndInitToolBar(){
        smartTitleBar = findViewById(R.id.qmi_title_bar)
        smartTitleBar?.let {
            it.setLeftViewClickListener(View.OnClickListener {
                this@BaseMVPActivity.onBackPressed()
            })
        }
    }

    fun hideNavigationIcon(){
        smartTitleBar?.let {
            it.leftView.visibility = View.GONE
        }
    }

    protected fun setToolBarTitle(titleResId : Int){
        smartTitleBar?.let {
            it.titleView.setText(titleResId)
        }
    }

    protected fun setToolBarTitle(title : String){
        smartTitleBar?.let {
            it.titleView.text = title
        }
    }

    protected fun setEmptyToolBarTitle(){
        smartTitleBar?.let {
            it.titleView.text = ""
        }
    }

    private fun supportOrientationPage() : Boolean = false

    //如需设置横竖屏切换，activity的theme必须设置windowFullscreenfalse
    override fun setRequestedOrientation(requestedOrientation: Int) {
        if (!supportOrientationPage()
            && Build.VERSION.SDK_INT == Build.VERSION_CODES.O
            && isTranslucentOrFloating()) {
            KLog.i(AppConstants.LOG_TAG, "avoid calling setRequestedOrientation when Oreo.")
            return
        }
        super.setRequestedOrientation(requestedOrientation)
    }

    private fun fixOrientation(): Boolean {
        try {
            val field = Activity::class.java.getDeclaredField("mActivityInfo")
            field.isAccessible = true
            val o = field.get(this) as ActivityInfo
            o.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
            field.isAccessible = false
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return false
    }

    private fun isTranslucentOrFloating(): Boolean {
        var isTranslucentOrFloating = false
        try {
            val styleableRes = Class.forName("com.android.internal.R\$styleable").getField("Window").get(null) as IntArray
            val ta = obtainStyledAttributes(styleableRes)
            val m = ActivityInfo::class.java.getMethod("isTranslucentOrFloating", TypedArray::class.java)
            m.isAccessible = true
            isTranslucentOrFloating = m.invoke(null, ta) as Boolean
            m.isAccessible = false
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return isTranslucentOrFloating
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if(keyCode == KeyEvent.KEYCODE_BACK && event?.action == KeyEvent.ACTION_DOWN){
            this.onBackPressed()
            return true
        }
        return super.onKeyDown(keyCode, event)
    }

    override fun onBackPressed() {
        if (!FragmentHandleBackUtil.handleBackPress(this)) {
            KeyboardUtils.hideSoftInput(this)

            this.finish()
            overridePendingTransition(R.anim.cbase__slide_in_from_left, R.anim.cbase__slide_out_to_right)
        }
    }

    override fun onStart() {
        super.onStart()
        NetworkManager.getDefault().registerObserver(this)
    }
    override fun onStop() {
        super.onStop()
        NetworkManager.getDefault().unregisterObserver(this)
    }

    override fun onDestroy() {
        AppManager.getInstance().removeActivity(this)
        BusProvider.getInstance().unregister(this)
        super.onDestroy()
        UIHelper.hideStatus()
        UIHelper.hideLoading()
    }

    fun requestSinglePermission(permissionName: String, explanationMessage: String? = null,
                                iPermissionReallyDeclinedCallBack : ((permissionName: String) -> Unit) ?= PermissionReallyDeclinedImpl(),
                                iPermissionResultCallBack: (Boolean) -> Unit){
        RuntimePermissionUtil(this@BaseMVPActivity).requestSinglePermission(permissionName,
            explanationMessage,
            object : RuntimePermissionUtil.RequestPermission{
                override fun onRequestPermissionFailureWithAskNeverAgain(permissionName: String) {
                    iPermissionReallyDeclinedCallBack?.invoke(permissionName)
                    iPermissionResultCallBack.invoke(false)
                }

                override fun onRequestPermissionSuccess() {
                    iPermissionResultCallBack.invoke(true)
                }

                override fun onRequestPermissionFailure(permissionName: String?) {
                    iPermissionResultCallBack.invoke(false)
                }
            })
    }

    @Subscribe
    fun onShowAPIErrorToastEvent(event : CommonBusEvent.ShowAPIErrorToastEvent){
        when(event.apiErrorToast){
            APIErrorToast.TimeoutError ->{
                ToastHelper.toastMessage(R.string.timeout_error)
            }
            APIErrorToast.ServerError ->{
                ToastHelper.toastMessage(R.string.server_error)
            }
            APIErrorToast.PathNotFoundError ->{
                ToastHelper.toastMessage(R.string.not_find_url_path_error)
            }
            APIErrorToast.UnknownError ->{
                ToastHelper.toastMessage(R.string.unknown_error)
            }
        }
    }

    @Subscribe
    fun onShowMessageEvent(event: CommonBusEvent.ShowMessageEvent) {
        if (this.javaClass.simpleName == ActivityUtils.getCurrentActivityName()) {
            UIHelper.hideStatus()

            val msgId = event.msgId
            if (!TextUtils.isEmpty(event.msg)) {
                UIHelper.showStatusDialog(this, event.type, event.msg ?: "")
            } else if (msgId != null) {
                UIHelper.showStatusDialog(this, event.type, getString(msgId) ?: "")
            }
        }
    }

    @Subscribe
    fun onShowLoadingEvent(event: CommonBusEvent.ShowLoadingEvent) {
        if (this.javaClass.simpleName == ActivityUtils.getCurrentActivityName()) {
            if (event.show) {
                UIHelper.showLoading(this)
            } else {
                UIHelper.hideLoading()
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onAppComeForegroundEvent(event : CommonBusEvent.AppComeForegroundEvent){
        if (this.javaClass.simpleName == ActivityUtils.getCurrentActivityName() && AppUtils.isAppForeground()) {
        }
    }

    private var needLoginDialog : CommonHorizontalActionsDialog?=null

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onNeedTokenEvent(event : CommonBusEvent.NeedTokenEvent){
        if (this.javaClass.simpleName == ActivityUtils.getCurrentActivityName() && AppUtils.isAppForeground()) {
            if(needLoginDialog?.isResumed == true){
                return
            }

            needLoginDialog = CommonHorizontalActionsDialog.generate {
                setTitle("请先登录")

                setConfirmBtnLabel(UIUtils.getString(R.string.common_confirm)) {
                    if(event.postCardPath != null && event.postCardBundle != null){
                        ARouter.getInstance().build(ARouterPathConstants.PATH_SIGN_IN)
                                .with(BundleHelper()
                                        .putString(AppConstants.PARAM_POSTCARD_PATH, event.postCardPath)
                                        .putBundle(AppConstants.PARAM_POSTCARD_BUNDLE, event.postCardBundle)
                                        .build())
                                .withTransition(R.anim.cbase__slide_in_from_right, R.anim.cbase__slide_out_to_left)
                                .greenChannel()
                                .navigation()
                    } else{
                        ARouter.getInstance().build(ARouterPathConstants.PATH_SIGN_IN)
                                .withTransition(R.anim.cbase__slide_in_from_right, R.anim.cbase__slide_out_to_left)
                                .greenChannel()
                                .navigation()
                    }
                }
                setCancelBtnLabel(UIUtils.getString(R.string.common_cancel))
                create()
            }
            needLoginDialog?.show(supportFragmentManager, "need_login")
        }
    }

    private var loginExpiredDialog : CommonHorizontalActionsDialog?=null
    @Subscribe
    fun onTokenExpiredEvent(event : CommonBusEvent.TokenExpiredEvent){
        if (this.javaClass.simpleName == ActivityUtils.getCurrentActivityName() && AppUtils.isAppForeground()) {
            if(loginExpiredDialog?.isResumed == true){
                return
            }

            //token 过期，清空退出IM服务，清空本地用户数据
            BusProvider.getInstance().post(CommonBusEvent.TokenChangeEvent(authorizated = false))
            AppAccount.clear()

            loginExpiredDialog = CommonHorizontalActionsDialog.generate {
                setTitle("您的账户已过期，请重新登录")

                setConfirmBtnLabel(UIUtils.getString(R.string.common_confirm)) {
                    ARouter.getInstance().build(ARouterPathConstants.PATH_SIGN_IN)
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                            .navigation()
                    this@BaseMVPActivity.finish()
                }
                create()
            }
            loginExpiredDialog?.show(supportFragmentManager, "token_expired")
        }
    }
}
